package service

import (
	"errors"
	"seat-service/initialization"
	"seat-service/model"
	"seat-service/model/dto"
	"time"
)

type ReservationService struct {
}

func (*ReservationService) QueryReservation(page, pageSize int) (dto.ReservationReturnDto, error) {

	res := make([]dto.ReservationDto, 0)

	var record int64
	err := initialization.DB.Debug().
		Table("reserves r1").
		Joins("JOIN seats s1 ON r1.seat_id = s1.id").
		Joins("JOIN classrooms c1 ON s1.classroom_id = c1.id").
		Joins("JOIN buildings b1 ON s1.building_id = b1.id").
		Joins("JOIN students s2 ON r1.student_id = s2.id").
		Where("r1.deleted_at IS NULL AND s1.deleted_at IS NULL AND c1.deleted_at IS NULL AND b1.deleted_at IS NULL AND s2.deleted_at IS NULL").
		Select("r1.id, s2.name, s2.student_number, b1.name AS building_name, s1.seat_number, r1.appointment_time_start, r1.appointment_time_end, r1.reserve_status,c1.location,r1.created_at").
		Count(&record).Error
	if err != nil {
		return dto.ReservationReturnDto{}, err
	}
	//页数
	pages := (record + int64(pageSize) - 1) / int64(pageSize)
	err = initialization.DB.Debug().
		Table("reserves r1").
		Joins("JOIN seats s1 ON r1.seat_id = s1.id").
		Joins("JOIN classrooms c1 ON s1.classroom_id = c1.id").
		Joins("JOIN buildings b1 ON s1.building_id = b1.id").
		Joins("JOIN students s2 ON r1.student_id = s2.id").
		Where("r1.deleted_at IS NULL AND s1.deleted_at IS NULL AND c1.deleted_at IS NULL AND b1.deleted_at IS NULL AND s2.deleted_at IS NULL").
		Select("r1.id, s2.name, s2.student_number, b1.name AS building_name, s1.seat_number, r1.appointment_time_start, r1.appointment_time_end, r1.reserve_status,c1.location,r1.created_at").
		Offset((page - 1) * pageSize).Limit(pageSize).
		Scan(&res).Error

	return dto.ReservationReturnDto{
		Reservation: res,
		Record:      record,
		Pages:       pages,
	}, err
}
func (*ReservationService) QueryConditionReservation(page, pageSize int, name, studentNumber, building, classroom, seat, reserveStatus string, start, end time.Time) (dto.ReservationReturnDto, error) {
	res := make([]dto.ReservationDto, 0)

	var record int64
	err := initialization.DB.Debug().
		Table("reserves r1").
		Joins("JOIN seats s1 ON r1.seat_id = s1.id").
		Joins("JOIN classrooms c1 ON s1.classroom_id = c1.id").
		Joins("JOIN buildings b1 ON s1.building_id = b1.id").
		Joins("JOIN students s2 ON r1.student_id = s2.id").
		Where("s2.name LIKE ? AND s2.student_number LIKE ? AND b1.name LIKE ? AND c1.location LIKE ? AND s1.seat_number LIKE ? AND r1.reserve_status LIKE ? AND appointment_time_start>? AND appointment_time_end<? AND r1.deleted_at IS NULL AND s1.deleted_at IS NULL AND c1.deleted_at IS NULL AND b1.deleted_at IS NULL AND s2.deleted_at IS NULL",
			name, studentNumber, building, classroom, seat, reserveStatus, start, end).
		Select("r1.id, s2.name, s2.student_number, b1.name AS building_name, s1.seat_number, r1.appointment_time_start, r1.appointment_time_end, r1.reserve_status,c1.location,r1.created_at").
		Count(&record).Error
	if err != nil {
		return dto.ReservationReturnDto{}, err
	}
	//页数
	pages := (record + int64(pageSize) - 1) / int64(pageSize)
	err = initialization.DB.Debug().
		Table("reserves r1").
		Joins("JOIN seats s1 ON r1.seat_id = s1.id").
		Joins("JOIN classrooms c1 ON s1.classroom_id = c1.id").
		Joins("JOIN buildings b1 ON s1.building_id = b1.id").
		Joins("JOIN students s2 ON r1.student_id = s2.id").
		Where("s2.name LIKE ? AND s2.student_number LIKE ? AND b1.name LIKE ? AND c1.location LIKE ? AND s1.seat_number LIKE ? AND r1.reserve_status LIKE ? AND appointment_time_start>? AND appointment_time_end<? AND r1.deleted_at IS NULL AND s1.deleted_at IS NULL AND c1.deleted_at IS NULL AND b1.deleted_at IS NULL AND s2.deleted_at IS NULL",
			name, studentNumber, building, classroom, seat, reserveStatus, start, end).
		Select("r1.id, s2.name, s2.student_number, b1.name AS building_name, s1.seat_number, r1.appointment_time_start, r1.appointment_time_end, r1.reserve_status,c1.location,r1.created_at").
		Offset((page - 1) * pageSize).Limit(pageSize).
		Scan(&res).Error

	return dto.ReservationReturnDto{
		Reservation: res,
		Record:      record,
		Pages:       pages,
	}, err
}

func (*ReservationService) CancelReservation(id uint) error {
	var res model.Reserve
	err := initialization.DB.Model(&model.Reserve{}).Where("id=?", id).Find(&res).Error
	if err != nil {
		return err
	}
	if res.ReserveStatus != 0 {
		return errors.New("非法修改")
	}
	res.ReserveStatus = 3
	err = initialization.DB.Updates(&res).Error
	if err != nil {
		return err
	}
	return nil
}
